package chen.web.back.client.system;

import chen.web.back.client.FormDataBuilder;
import chen.web.back.client.UrlHelper;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Status;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;

public class MailboxForm extends LayoutContainer {

	private static final String Email_Regex = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

	@Override
	protected void onRender(Element parent, int index) {
		// TODO Auto-generated method stub
		super.onRender(parent, index);
		VerticalPanel vp = new VerticalPanel();
		vp.add(createForm());
		add(vp);
		loadData();
	}

	private FieldSet useSMTP = null;
	private TextField<String> senderEmail = null;
	private TextField<String> smtpHost = null;
	private TextField<String> username = null;
	private TextField<String> password = null;
	private Button saveButton = null;
	private Button reset = null;
	private EmailAccount account = new EmailAccount();
	private Status status = null;
	private FormPanel createForm() {
		FormPanel simple = new FormPanel();
		simple.setHeading("邮箱设置");
		simple.setFrame(true);
		simple.setWidth(350);

		senderEmail = new TextField<String>();
		senderEmail.setFieldLabel("邮箱地址");
		senderEmail.setAllowBlank(false);
		senderEmail.getFocusSupport().setPreviousId(simple.getButtonBar().getId());
		simple.add(senderEmail);

		useSMTP = new FieldSet();
		useSMTP.setHeading("使用SMTP帐号发送");  
		useSMTP.setCheckboxToggle(true); 
		useSMTP.setExpanded(false);
	    
	    FormLayout layout = new FormLayout();  
	    layout.setLabelWidth(65);  
	    useSMTP.setLayout(layout);
		
	    smtpHost = new TextField<String>();
	    smtpHost.setFieldLabel("smtp主机");
	    smtpHost.setAllowBlank(false);
		useSMTP.add(smtpHost);

		username = new TextField<String>();
		username.setFieldLabel("帐号");
		useSMTP.add(username);

		password = new TextField<String>();
		password.setFieldLabel("密码");
		useSMTP.add(password);
		
		simple.add(useSMTP);
		
		status = new Status();
		status.setBusy("please wait...");
		status.hide();
		status.setAutoWidth(true);
		simple.getButtonBar().add(status);
		
		saveButton = new Button("保存");
		saveButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
			public void componentSelected(ButtonEvent ce) {
				saveData();
			}
		});
		saveButton.disable();
		simple.addButton(saveButton);
		
		reset = new Button("重置");
		reset.addSelectionListener(new SelectionListener<ButtonEvent>() {
			public void componentSelected(ButtonEvent ce) {
				loadData();
			}
		});
		reset.disable();
		simple.addButton(reset);

		Button test = new Button("发送测试邮件");
		test.addSelectionListener(new SelectionListener<ButtonEvent>() {
			public void componentSelected(ButtonEvent ce) {
				final MessageBox box = MessageBox.prompt("发送测试邮件", "请输入收件人地址:");
				Listener<MessageBoxEvent> callback = new Listener<MessageBoxEvent>(){
					@Override
					public void handleEvent(MessageBoxEvent be) {
						// TODO Auto-generated method stub
						String address = be.getValue();
						Button b = be.getButtonClicked();
						if(b.getText().trim().equalsIgnoreCase("cancel")){
							return;
						}
						if(address != null && address.matches(Email_Regex)){
							sendTestEmail(be.getValue());	
						} else {
							MessageBox.alert("输入错误", "邮件地址格式不正确", null);
						}
					}
				};
				box.addCallback(callback);
			}
		});
		simple.addButton(test);
		simple.setButtonAlign(HorizontalAlignment.RIGHT);
		
		Listener<BaseEvent> inputListener = new Listener<BaseEvent>(){
			@Override
			public void handleEvent(BaseEvent be) {
				// TODO Auto-generated method stub
				if(!senderEmail.getValue().equals(account.getSenderEmail()) ||
						!smtpHost.getValue().equals(account.getSmtpHost())	||
						!username.getValue().equals(account.getUsername()) ||
						!password.getValue().equals(account.getPassword())	||
						!useSMTP.isExpanded()==account.isUseSMTP()
				){
					saveButton.enable();
					reset.enable();
				}
			}
			
		};
		
		useSMTP.addListener(Events.OnChange, inputListener);
		senderEmail.addListener(Events.OnChange, inputListener);
		smtpHost.addListener(Events.OnChange, inputListener);
		username.addListener(Events.OnChange, inputListener);
		password.addListener(Events.OnChange, inputListener);
		
		senderEmail.addListener(Events.OnKeyPress, inputListener);
		smtpHost.addListener(Events.OnKeyPress, inputListener);
		username.addListener(Events.OnKeyPress, inputListener);
		password.addListener(Events.OnKeyPress, inputListener);
		
		return simple;
	}
	
	private void saveData(){
		status.show();
		saveButton.disable();
		reset.disable();
		RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, UrlHelper.toAbsolute("/config/emailAccount"));
		builder.setHeader("Content-Type", "application/json; charset=UTF-8");
		try {
			FormDataBuilder fdb = new FormDataBuilder();
			fdb.addProperty("useSMTP", Boolean.toString(useSMTP.isExpanded()));
			fdb.addProperty("smtpHost", smtpHost.getValue());
			fdb.addProperty("senderEmail", senderEmail.getValue());
			fdb.addProperty("username", username.getValue());
			fdb.addProperty("password", password.getValue());
			builder.sendRequest(fdb.toJSONString(), new RequestCallback(){

				@Override
				public void onError(Request arg0, Throwable arg1) {
					// TODO Auto-generated method stub
					displayError("Couldn't retrieve JSON");
				}

				@Override
				public void onResponseReceived(Request request, Response response) {
					// TODO Auto-generated method stub
					if (200 == response.getStatusCode()) {
						JSONValue json = JSONParser.parseStrict(response
								.getText());
						JSONValue process = json.isObject().get("success");
						if(process != null && process.isBoolean().booleanValue()){
							loadData();
						} else {
							displayError(response.getText());
						}
						status.hide();
					}  else {
						displayError("Couldn't retrieve JSON ("
								+ response.getStatusText() + ")");
					}
				}
				
			});
		} catch (RequestException e) {
			// TODO Auto-generated catch block
			displayError("Couldn't retrieve JSON");
		}
	}
	

	public void loadData(){
		status.show();
		saveButton.disable();
		reset.disable();
		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, UrlHelper.toAbsolute("/config/emailAccount"));
		try {
			builder.sendRequest(null, new RequestCallback(){

				@Override
				public void onError(Request arg0, Throwable arg1) {
					// TODO Auto-generated method stub
					displayError("Couldn't retrieve JSON");
				}

				@Override
				public void onResponseReceived(Request request, Response response) {
					// TODO Auto-generated method stub
					if (200 == response.getStatusCode()) {
						JSONValue json = JSONParser.parseStrict(response
								.getText());
						JSONObject returnObject = json.isObject().get("returnObject").isObject();
						Boolean useSMTP = returnObject.get("useSMTP").isBoolean().booleanValue();
						String senderEmail = returnObject.get("senderEmail").isString().stringValue();
						String smtpHost = returnObject.get("smtpHost").isString().stringValue();
						String username = returnObject.get("username").isString().stringValue();
						String password = returnObject.get("password").isString().stringValue();
						account.setUseSMTP(useSMTP);
						account.setSenderEmail(senderEmail);
						account.setSmtpHost(smtpHost);
						account.setUsername(username);
						account.setPassword(password);
						loadFormData();
						status.hide();
					}  else {
						displayError("Couldn't retrieve JSON ("
								+ response.getStatusText() + ")");
					}
				}
				
			});
		} catch (RequestException e) {
			// TODO Auto-generated catch block
			displayError("Couldn't retrieve JSON");
		}
	}
	
	private void sendTestEmail(String address){
		RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, UrlHelper.toAbsolute("/config/emailAccount/test"));
		builder.setHeader("Content-Type", "application/x-www-form-urlencoded");
		try {
			FormDataBuilder fdb = new FormDataBuilder();
			fdb.addProperty("address", address);
			builder.sendRequest(fdb.toQueryString(), new RequestCallback(){

				@Override
				public void onError(Request arg0, Throwable arg1) {
					// TODO Auto-generated method stub
					displayError("Couldn't retrieve JSON");
				}

				@Override
				public void onResponseReceived(Request request, Response response) {
					// TODO Auto-generated method stub
					if (200 == response.getStatusCode()) {
						JSONValue json = JSONParser.parseStrict(response
								.getText());
						String process = json.isObject().get("process").isString().stringValue();
						if(!"success".equals(process)){
							displayError(response.getText());
						} 
					}  else {
						displayError("Couldn't retrieve JSON ("
								+ response.getStatusText() + ")");
					}
				}
				
			});
		} catch (RequestException e) {
			// TODO Auto-generated catch block
			displayError("Couldn't retrieve JSON");
		}
	}
	
	private void loadFormData(){
		useSMTP.setExpanded(account.isUseSMTP());
		senderEmail.setValue(account.getSenderEmail());
		smtpHost.setValue(account.getSmtpHost());
		username.setValue(account.getUsername());
		password.setValue(account.getPassword());
	}
	
	private void displayError(String message){
		status.hide();
		saveButton.enable();
		reset.enable();
		MessageBox.alert("出错", message, null);
	}
}
